home *** CD-ROM | disk | FTP | other *** search
/ MacWorld Secrets (4th Edition) / Mac Secrets CD 4th Ed.toast / Shareware & Freeware / KeyQuencer 1.2.2 / Developer’s toolkit / Common code / A4Globals.h next >
C/C++ Source or Header  |  1995-12-16  |  8KB  |  209 lines

  1. // =============================================================================
  2. // COMPILER-INDEPENDENT GLOBAL STORAGE
  3. // ©1994-96 Alessandro Levi Montalcini <alm@torino.alpcom.it>
  4. // The latest version is available on ftp://ftp.alpcom.it/software/mac/LMontalcini
  5. // This text looks best in monaco 9 font, 4 spaces per tab, no wrapping
  6.  
  7. // WARNING: THIS HEADER SHOULD ONLY BE INCLUDED ONCE THROUGHOUT THE PROJECT
  8.  
  9. // Unaltered copies of this file may be freely distributed; you may use this
  10. // code in your projects without asking my permission and modify it for your
  11. // personal use, but you should not distribute any modified versions. Send
  12. // me your additions if you want them to be included in the next version.
  13.  
  14. // If you use this header in your projects, I'd be happy to get some credits
  15. // or to receive a copy of the program. However, this is absolutely not
  16. // required if you can't do it for any reason.
  17.  
  18. //==============================================================================
  19. // Original code and comments are copyright ©Alessandro Levi Montalcini (ALM)
  20. // ALM 11/23/94: released as part of the KeyQuencer developer's toolkit
  21. // ALM 04/01/95: changed defined(powerc) to GENERATINGPOWERPC
  22. // ALM 05/18/95: merged ALM and RMT macros, added comments and sample code
  23.  
  24. // Additions to A4Globals.h by Robert M. Thorne of Aladdin Systems, Inc. (RMT)
  25. // RMT Add code to make this conditional if A4 based.
  26. // RMT 4/20/95: fixed macro for MWerks (was redefining GLOBALS_ALWAYS_AVAILABLE)
  27. //==============================================================================
  28.  
  29. #ifndef _H_a4globals
  30. #define _H_a4globals
  31.  
  32. //==============================================================================
  33. // Check if the current project needs to set up the environment before accessing
  34. // its global variables. Globals are always available in PowerPC code fragments
  35. // and in 68K applications, whereas 68K A4-based projects have to set up the A4
  36. // register before using the globals and restore it when they are done.
  37. // Note: this method can't be used to gain access to 68K A5-based application
  38. // globals from callback routines such as VBL or Time Manager tasks.
  39. // (this section was originally conceived by RMT)
  40.  
  41. #if GENERATINGPOWERPC    // any PowerPC compiler
  42.  
  43.     #define GLOBALS_ALWAYS_AVAILABLE 1
  44.  
  45. #elif defined(THINK_C)    // Think C 68K
  46.  
  47.     #if __option(a4_globals)
  48.         #define GLOBALS_ALWAYS_AVAILABLE 0
  49.     #else
  50.         #define GLOBALS_ALWAYS_AVAILABLE 1
  51.     #endif
  52.  
  53. #elif defined(__MWERKS__)    // CodeWarrior 68K
  54.  
  55.     #if __A5__
  56.         #define GLOBALS_ALWAYS_AVAILABLE 1
  57.     #else
  58.         #define GLOBALS_ALWAYS_AVAILABLE 0
  59.     #endif
  60.  
  61. #else    // unknown compiler, stop here
  62.  
  63.     #error unsupported compiler
  64.  
  65. #endif    // end of project type check
  66.  
  67. //==============================================================================
  68. // The following macros can be used by any project to set up and restore the
  69. // globals environment. Both the Think C and CodeWarrior headers include static
  70. // code, so this header should only be included once throughout the project.
  71. //
  72. // The #include "A4Globals.h" statement should be at the beginning of the source
  73. // file containing the main routine; you should declare a "world" local variable
  74. // of type "long" and call MAIN_SETUP_GLOBALS(world) at the beginning of the
  75. // main routine and MAIN_RESTORE_GLOBALS(world) at the end. Remember not to use
  76. // any "return" statement between the two macros, or you'll return to the caller
  77. // without restoring the A4 register (which can be really bad). Also, don't try
  78. // to use global variables after the MAIN_RESTORE_GLOBALS macro; if you need a
  79. // global for your function result, copy it to a local variable. You can use the
  80. // TEMP_SETUP_GLOBALS and TEMP_RESTORE_GLOBALS macros in routines that are
  81. // called without going through the main entry point, as long as they are in
  82. // the same file as the main routine. See below for more information on how to
  83. // access global variables from code that lives in other source files and gets
  84. // called without going through main.
  85.  
  86. #if GLOBALS_ALWAYS_AVAILABLE    // PowerPC code fragment or 68K application
  87.  
  88.     #define MAIN_SETUP_GLOBALS(x)    { x = 0; }    // to avoid "unused var" warnings
  89.     #define MAIN_RESTORE_GLOBALS(x)
  90.     #define TEMP_SETUP_GLOBALS(x)    { x = 0; }
  91.     #define TEMP_RESTORE_GLOBALS(x)
  92.  
  93. #elif defined(THINK_C)    // Think C A4-based project
  94.  
  95.     #include <SetUpA4.h>
  96.     #define MAIN_SETUP_GLOBALS(x)    { RememberA0(); SetUpA4(); asm { MOVE.L (A7)+, x } }
  97.     #define MAIN_RESTORE_GLOBALS(x)    { asm { MOVE.L x, -(A7) } RestoreA4(); }
  98.     #define TEMP_SETUP_GLOBALS(x)    { SetUpA4(); asm { MOVE.L (A7)+, x } }
  99.     #define TEMP_RESTORE_GLOBALS(x)    { asm { MOVE.L x, -(A7) } RestoreA4(); }
  100.     
  101. #elif defined(__MWERKS__)    // CodeWarrior A4-based project
  102.  
  103.     #include <A4Stuff.h>
  104.     #include <SetUpA4.h>
  105.     #define MAIN_SETUP_GLOBALS(x)    { x = SetCurrentA4(); RememberA4(); }
  106.     #define MAIN_RESTORE_GLOBALS(x)    { (void)SetA4(x); }
  107.     #define TEMP_SETUP_GLOBALS(x)    { x = SetUpA4(); }
  108.     #define TEMP_RESTORE_GLOBALS(x)    { (void)RestoreA4(x); }
  109.  
  110. #endif    // end of compiler-specific macros
  111.  
  112. //==============================================================================
  113. // After you set up the environment, all the project globals are available to
  114. // your code no matter what source file it lives in. In some cases, however,
  115. // your code is called without going through the main entry point (callback
  116. // routines, periodic tasks, trap patches and so forth). If this code is in
  117. // the same file as the main routine, you can use TEMP_SETUP_GLOBALS and
  118. // TEMP_RESTORE_GLOBALS; otherwise, you should add a couple of routines to
  119. // your main source file whose only task in life is to set up and restore the
  120. // environment for you. Here's a simple example with two source files that
  121. // shows how to use the macros correctly:
  122. /*
  123. ------------------------ FILE: main.c ------------------------
  124.  
  125. #include "A4Globals.h"
  126. #include "other.h"
  127.  
  128. // Global variables:
  129. long gNumTimesCalled;
  130.  
  131. // Main entry point; set up globals, call routines and install callbacks:
  132. pascal OSErr main(void)
  133. {
  134.     long    world;
  135.     
  136.     MAIN_SETUP_GLOBALS(world);
  137.     DoSomethingFromMainFile();
  138.     DoSomethingFromOtherFile();
  139.     InstallCallbackRoutine(CallbackFromMainFile);
  140.     InstallCallbackRoutine(CallbackFromOtherFile);
  141.     MAIN_RESTORE_GLOBALS(world);
  142.     return noErr;
  143. }
  144.  
  145. // Called when the globals are already available, no need to set them up again:
  146. void DoSomethingFromMainFile(void)
  147. {
  148.     gNumTimesCalled = 0L;
  149. }
  150.  
  151. // Called without going through main, set up globals with TEMP_SETUP_GLOBALS:
  152. pascal long CallbackFromMainFile(void)
  153. {
  154.     long    world, timesCalled;
  155.     
  156.     TEMP_SETUP_GLOBALS(world);
  157.     ++gNumTimesCalled;
  158.     timesCalled = gNumTimesCalled;
  159.     TEMP_RESTORE_GLOBALS(world);
  160.     return timesCalled;
  161. }
  162.  
  163. // Set up the globals environment for routines that live in other files:
  164. long SetupGlobalsWorld(void)
  165. {
  166.     long    world;
  167.     
  168.     TEMP_SETUP_GLOBALS(world);
  169.     return world;
  170. }
  171.  
  172. // Restore the globals environment for routines that live in other files:
  173. void RestoreGlobalsWorld(long world)
  174. {
  175.     TEMP_RESTORE_GLOBALS(world);
  176. }
  177.  
  178. ------------------------ FILE: other.c ------------------------
  179.  
  180. #include "main.h"
  181.  
  182. // Global variables:
  183. extern long gNumTimesCalled;
  184.  
  185. // Although not in the main file, this is called when the globals are already available:
  186. void DoSomethingFromOtherFile(void)
  187. {
  188.     gNumTimesCalled = 0L;
  189. }
  190.  
  191. // Called without going through main, can't use the macros; call SetupGlobalsWorld instead:
  192. pascal long CallbackFromOtherFile(void)
  193. {
  194.     long    world, timesCalled;
  195.     
  196.     world = SetupGlobalsWorld();
  197.     ++gNumTimesCalled;
  198.     timesCalled = gNumTimesCalled;
  199.     RestoreGlobalsWorld(world);
  200.     return timesCalled;
  201. }
  202. */
  203. //==============================================================================
  204.  
  205. #endif    // _H_a4globals
  206.  
  207. //==============================================================================
  208.  
  209.